package ru.dc.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.VFS;
import ru.dc.object.ServerInfo;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <pre>
 * User: Penkov Vladimir
 * Date: 03.11.2010
 * Time: 15:28:44
 * </pre>
 */
public class PublicHubListUtils {

    private static Log logger = LogFactory.getLog(PublicHubListUtils.class);

    /**
     * Возвращает информацию о публичных хабах, расположенную по адресу url
     * @param url адрес, по которому располагается архив со списком публичных хабов.
     * @return информация о хабах
     */
    public static Map<ServerInfo, Map<String, String>> getPublicHubList(String url) {

        Map<ServerInfo, Map<String, String>> res = new HashMap<ServerInfo, Map<String, String>>();

        try {
            FileSystemManager fsManager = VFS.getManager();
            FileObject fileList = fsManager.resolveFile("bz2:" + url + "!hublist.xml");
            BufferedReader in = new BufferedReader(new InputStreamReader(fileList.getContent().getInputStream()));

            //несмотря на то, что список хабов - это xml документ, формируется он как бог на душу положит, так что
            //в большинстве случаев разобрать документ анализатором не получается (в некоторых случаях это вообще не
            // валидная xml). Поэтому разбор сделаем через регулярные выражения
            StringBuilder sb = new StringBuilder();
            String s;
            while ((s = in.readLine())!=null) {
                sb.append(s);
            }

            Pattern hubsPattern = Pattern.compile("<Hub .*?/?>");
            Pattern attrPattern = Pattern.compile("(\\w+)=\"(.*?)\"");
            Matcher m = hubsPattern.matcher(sb);
            List<String> tokens = new ArrayList<String>();
            while (m.find()) {
                tokens.add(m.group());
            }
            logger.debug(tokens.size()+" hubs found from url "+url);

            for (String token : tokens) {
                Matcher m1 = attrPattern.matcher(token);
                Map<String, String> attrs = new HashMap<String, String>();
                while (m1.find()) {
                    attrs.put(m1.group(1), m1.group(2));
                }

                String addr = attrs.get("Address");
                if (addr.indexOf("://")>=0) {
                    addr = addr.substring(addr.indexOf("://")+3);
                }

                ServerInfo si = new ServerInfo();
                String[] addr_port = addr.split(":");
                try {
                    final Integer port = addr_port.length>=2 ? new Integer(addr_port[1]) : 411; 
                    si.setAddress(addr_port[0]);
                    si.setPort(port);
                    res.put(si, attrs);
                } catch (NumberFormatException e) {
                    logger.warn("Wrong format of source url: "+addr);
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }


}
